package logic_setting_role

import (
	v1 "Sailor/app/Sailor-console-server/api/api_setting_role/v1"
	"Sailor/app/Sailor-console-server/internal/dao"
	"Sailor/app/Sailor-console-server/internal/model/do"
	"Sailor/app/Sailor-console-server/internal/model/entity"
	"Sailor/app/Sailor-console-server/utility/utility_casbin"
	"context"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/google/uuid"
)

func (s *sSettingRole) LogicSettingRolePermissionUpdate(ctx context.Context, req *v1.SettingRolePermissionUpdateReq) (res *v1.SettingRolePermissionUpdateRes, err error) {
	err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = dao.SysRoleMenu.Ctx(ctx).TX(tx).Where(dao.SysRoleMenu.Columns().RoleCode, req.RoleCode).Unscoped().Delete()
		if err != nil {
			g.Log().Error(ctx, err)
			return err
		}
		for _, v := range req.AuthMenu {
			_, err = dao.SysRoleMenu.Ctx(ctx).TX(tx).Insert(&do.SysRoleMenu{
				Uuid:     uuid.New().String(),
				RoleCode: req.RoleCode,
				MenuId:   v,
			})
			if err != nil {
				g.Log().Error(ctx, err)
				return err
			}
		}

		_, err = dao.CasbinRule.Ctx(ctx).TX(tx).Delete(dao.CasbinRule.Columns().V0, req.RoleCode)
		if err != nil {
			g.Log().Error(ctx, err)
			return err
		}

		var apis []entity.SysApi
		err = dao.SysApi.Ctx(ctx).TX(tx).Where(dao.SysApi.Columns().Uuid, req.AuthApi).Scan(&apis)
		if err != nil {
			g.Log().Error(ctx, err)
			return err
		}
		for _, v := range apis {
			_, err = dao.CasbinRule.Ctx(ctx).TX(tx).Insert(&do.CasbinRule{
				Uuid:  uuid.New().String(),
				Ptype: "p",
				V0:    req.RoleCode,
				V1:    v.ApiPath,
				V2:    v.ApiMethod,
			})
			if err != nil {
				g.Log().Error(ctx, err)
				return err
			}
		}
		return nil
	})
	if err != nil {
		g.Log().Error(ctx, err)
		return nil, gerror.New("更新权限列表失败")
	}

	err = utility_casbin.CasBin(ctx).LoadPolicy()
	if err != nil {
		g.Log().Error(ctx, err)
		return nil, gerror.New("重载权限列表失败")
	}

	return &v1.SettingRolePermissionUpdateRes{}, nil
}
